package com.reminder.server;
/* code used and modified http://bradabrams.com/2011/05/google-io-session-overview-android-app-engine-a-developers-dream-combination*/

import com.google.android.c2dm.server.PMF;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.web.bindery.requestfactory.server.RequestFactoryServlet;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.servlet.ServletContext;

public class DataStore {


  /**
   * Remove this object from the data store.
   */
  public void delete(Long id) {
    PersistenceManager pm = PMF.get().getPersistenceManager();
    try {
      Task item = pm.getObjectById(Task.class, id);
      pm.deletePersistent(item);
    } finally {
      pm.close();
    }
  }

  /**
     * Find a {@link Task} by id.
     * 
     * @param id the {@link Task} id
     * @return the associated {@link Task}, or null if not found
     */
    @SuppressWarnings("unchecked")
    public Task find(Long id) {
      if (id == null) {
        return null;
      }
  
      PersistenceManager pm = PMF.get().getPersistenceManager();
      try {
        Query query = pm.newQuery("select from " + Task.class.getName()
            + " where id==" + id.toString() + " && emailAddress=='" + getUserEmail() + "'");
        List<Task> list = (List<Task>) query.execute();
        return list.size() == 0 ? null : list.get(0);
      } catch (RuntimeException e) {
        System.out.println(e);
        throw e;
      } finally {
        pm.close();
      }
    }

@SuppressWarnings("unchecked")
public List<Task> findAll() {
  PersistenceManager pm = PMF.get().getPersistenceManager();
  List<Task> list;
  try {
	  List<String> emails = findAcceptEmails() ;
	  Query query = pm.newQuery(Task.class);  
	  if (!emails.isEmpty()){
	  query.setFilter("emailAddress.contains(:emails) ||" + "emailAddress =='" + getUserEmail() + "'");
	  list = (List<Task>) query.execute(emails);}
	  else {
	  query = pm.newQuery("select from " + Task.class.getName()
	  	        + " where emailAddress=='" + getUserEmail() + "'");
	  	      list = (List<Task>) query.execute();
	  }
      if (list.size() == 0) {
           //Workaround for this issue:
           //http://code.google.com/p/datanucleus-appengine/issues/detail?id=24
          list.size();
        }

    return list;
  } catch (RuntimeException e) {
    System.out.println(e);
    throw e;
  } finally {
    pm.close();
  }
}



  /**
   * Persist this object in the datastore.
   */
  public Task update(Task item) {
    //set the user id (not sure this is where we should be doing this)
    item.setUserId(getUserId());
    item.setEmailAddress(getUserEmail());
    item.setUserGroup("empty"); 
    item.setNotified(Boolean.FALSE);
    if (item.getDueDate() == null) {
        Calendar c = Calendar.getInstance();
        c.set(2011, 5, 11);
        item.setDueDate(c.getTime());
    }
    PersistenceManager pm = PMF.get().getPersistenceManager();
    try {
      pm.makePersistent(item);
      return item;
    } finally {
      pm.close();
    }
  }
  
  public void updateUserGroup(String acceptEmail){
	  PersistenceManager pm = PMF.get().getPersistenceManager();
	  UserGroup userGroup = new UserGroup();
	  userGroup.setEmailAddress(getUserEmail());
	  userGroup.setAcceptEmail(acceptEmail);
	  userGroup.setAccepted(Boolean.FALSE);
	  try { 
		  pm.makePersistent(userGroup);
	  } finally{
		  pm.close();
	  } 
  }
  
  public void updateUserGroupForTheAcceptedUser(String acceptEmail){
	  PersistenceManager pm = PMF.get().getPersistenceManager();
	  UserGroup userGroup = new UserGroup();
	  userGroup.setEmailAddress(getUserEmail());
	  userGroup.setAcceptEmail(acceptEmail);
	  userGroup.setAccepted(Boolean.TRUE);
	  try { 
		  pm.makePersistent(userGroup);
	  } finally{
		  pm.close();
	  } 
  }
  
  @SuppressWarnings("unchecked")
  public List<String> findAcceptEmails() {
    PersistenceManager pm = PMF.get().getPersistenceManager();
    try {
      Query query = pm.newQuery("select acceptEmail from " + UserGroup.class.getName()
        + " where emailAddress=='" + getUserEmail() + "' && accepted == true");
      List<String> acceptEmails = (List<String>) query.execute();
      if (acceptEmails.size() == 0) {
          //Workaround for this issue:
          //http://code.google.com/p/datanucleus-appengine/issues/detail?id=24
    	  acceptEmails.size();
       }
      return acceptEmails;
    } catch (RuntimeException e) {
	System.out.println("exception in findAllInvites");
    System.out.println(e);
    throw e;
   } finally {
   pm.close();
   }
}
  
  @SuppressWarnings("unchecked")
  public List<String> findAcceptEmails2() {
    PersistenceManager pm = PMF.get().getPersistenceManager();
    try {
      Query query = pm.newQuery("select emailAddress from " + UserGroup.class.getName()
        + " where acceptEmail=='" + getUserEmail() + "' && accepted == true");
      List<String> acceptEmails = (List<String>) query.execute();
      if (acceptEmails.size() == 0) {
          //Workaround for this issue:
          //http://code.google.com/p/datanucleus-appengine/issues/detail?id=24
    	  acceptEmails.size();
       }
      return acceptEmails;
    } catch (RuntimeException e) {
	System.out.println("exception in findAllInvites");
    System.out.println(e);
    throw e;
   } finally {
   pm.close();
   }
}
  
  @SuppressWarnings("unchecked")
  public List<String> findAcceptEmailsFalse() {				
    PersistenceManager pm = PMF.get().getPersistenceManager();
    try {
      Query query = pm.newQuery("select emailAddress from " + UserGroup.class.getName()
        + " where acceptEmail=='" + getUserEmail() + "' && accepted == false");
      List<String> acceptEmails = (List<String>) query.execute();
      if (acceptEmails.size() == 0) {
          //Workaround for this issue:
          //http://code.google.com/p/datanucleus-appengine/issues/detail?id=24
    	  acceptEmails.size();
       }
      return acceptEmails;
    } catch (RuntimeException e) {
	System.out.println("exception in findAllInvites");
    System.out.println(e);
    throw e;
   } finally {
   pm.close();
   }
}
 
  @SuppressWarnings("unchecked")
  public Long findAcceptEmailsFalseObject(String acceptInvite) {
    PersistenceManager pm = PMF.get().getPersistenceManager();
    try {
      Query query = pm.newQuery("select id from " + UserGroup.class.getName()
        + " where emailAddress=='" + acceptInvite + "' && accepted == false && acceptEmail=='" + getUserEmail() +"'");
      List<Long> list = (List<Long> ) query.execute();
      return list.size() == 0 ? null : list.get(0);
    } catch (RuntimeException e) {
	System.out.println("exception in findAllInvites");
    System.out.println(e);
    throw e;
   } finally {
   pm.close();
   }
}
  
  public void updateUserGroupInvite(String acceptInvite) {
	    long inviteId = findAcceptEmailsFalseObject(acceptInvite);
	    PersistenceManager pm = PMF.get().getPersistenceManager();
	    
	    try {
            pm.currentTransaction().begin();
            UserGroup userInvite = pm.getObjectById(UserGroup.class, inviteId);
    	    userInvite.setAccepted(Boolean.TRUE);
            pm.makePersistent(userInvite);
            pm.currentTransaction().commit();
            updateUserGroupForTheAcceptedUser(acceptInvite);
        } catch (Exception ex) {
            pm.currentTransaction().rollback();
            throw new RuntimeException(ex);
        } finally {
            pm.close();
        }

	   
	  }
  
  @SuppressWarnings("unchecked")
  public List<Task> findAllNotNotified() {
    PersistenceManager pm = PMF.get().getPersistenceManager();
    List<Task> list;
    try {
  	  List<String> emails = findAcceptEmails() ;
  	  Query query = pm.newQuery(Task.class);  
  	  if (!emails.isEmpty()){
  	  query.setFilter("emailAddress.contains(:emails) ||" + "emailAddress =='" + getUserEmail() + "'");
  	  
  	  list = (List<Task>) query.execute(emails);}
  	  else {
  	  query = pm.newQuery("select from " + Task.class.getName()
  	  	        + " where emailAddress=='" + getUserEmail() + "'");
  	  	      list = (List<Task>) query.execute();
  	  }
        if (list.size() == 0) {
             //Workaround for this issue:
             //http://code.google.com/p/datanucleus-appengine/issues/detail?id=24
            list.size();
          }

      return list;
    } catch (RuntimeException e) {
      System.out.println(e);
      throw e;
    } finally {
      pm.close();
    }
  }
  
  public void updateTasksNotified(long taskId) {
	    PersistenceManager pm = PMF.get().getPersistenceManager();
	    
	    try {
          pm.currentTransaction().begin();
          Task taskNotified = pm.getObjectById(Task.class, taskId);
  	      taskNotified.setNotified(Boolean.TRUE);
          pm.makePersistent(taskNotified);
          pm.currentTransaction().commit();
      } catch (Exception ex) {
          pm.currentTransaction().rollback();
          throw new RuntimeException(ex);
      } finally {
          pm.close();
      }

	   
	  }
  
      
  public static String getUserId() {
    UserService userService = UserServiceFactory.getUserService();
    User user = userService.getCurrentUser();
    return user.getUserId();
  }
  
  public static String getUserEmail() {
	    UserService userService = UserServiceFactory.getUserService();
	    User user = userService.getCurrentUser();
	    return user.getEmail();
	  }
	  
  
	
  public static void sendC2DMUpdate(String message) {
	    UserService userService = UserServiceFactory.getUserService();
	    User user = userService.getCurrentUser();
		ServletContext context = RequestFactoryServlet.getThreadLocalRequest().getSession().getServletContext();
		SendMessage.sendMessage(context, user.getEmail(), message);
}


}
